package com.zhongshu.controller;

import com.zhongshu.common.utils.DateUtils;
import lombok.SneakyThrows;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * @ClassName: RedissonController
 * @Description: TODO
 * @author: 星~
 * @date: 2021/9/13 0013 下午 15:53
 */
@RequestMapping
@RestController
public class RedissonController {


    @Autowired
    RedissonClient redissonClient;


    @SneakyThrows
    @RequestMapping("A0")
    public  String A0() {
        RLock lock = redissonClient.getLock("lock");
        lock.lock();
        System.out.println("A方法 已获得到锁");
        Thread.sleep(10000);
        lock.unlock();
        System.out.println("A方法 锁已释放 ");
        return "ok";
    }

    @SneakyThrows
    @RequestMapping("B0")
    public String B0() {
        RLock lock = redissonClient.getLock("lock");
        lock.lock();
        System.out.println("B方法 已获得到锁");
        Thread.sleep(10000);
        lock.unlock();
        System.out.println("B方法 锁已释放 ");
        return "ok";
    }

    @SneakyThrows
    @RequestMapping("A1")
    public String A1() {
        RLock lock = redissonClient.getLock("lock");
        lock.lock(10L, TimeUnit.SECONDS);
        System.out.println(DateUtils.getCurrentTime());
        System.out.println("A方法 已获得到锁");
        return "ok";
    }

    @SneakyThrows
    @RequestMapping("B1")
    public String B1() {
        RLock lock = redissonClient.getLock("lock");
        lock.lock(10L, TimeUnit.SECONDS);
        System.out.println("B方法 已获得到锁");
        System.out.println(DateUtils.getCurrentTime());
        lock.unlock();
        return "ok";
    }


    @SneakyThrows
    @RequestMapping("A2")
    public String A2() {
        RLock lock = redissonClient.getLock("lock");
        lock.lock(10L, TimeUnit.SECONDS);
        System.out.println("A方法 已获得到锁" + DateUtils.getCurrentTime());
        return "ok";
    }

    @SneakyThrows
    @RequestMapping("B2")
    public String B2() {
        RLock lock = redissonClient.getLock("lock");
        // 最多等待 11秒 加锁三秒
        boolean b = lock.tryLock(11, 3, TimeUnit.SECONDS);
        if (b) {
            System.out.println("B方法 已获得到锁" + DateUtils.getCurrentTime());
        } else {
            System.out.println("B方法 没有获得到锁" + DateUtils.getCurrentTime());
        }
        return "ok";
    }

    /**
     * 按顺序 进入
     *
     * @return
     */
    @SneakyThrows
    @RequestMapping("A3")
    public String A3() {
        RLock lock = redissonClient.getFairLock("fairLock");
        lock.lock();
        System.out.println("A方法 已获得到公平锁" + DateUtils.getCurrentTime());
        return "ok";
    }


    @SneakyThrows
    @RequestMapping("B3")
    public String B3() {
        RLock lock = redissonClient.getFairLock("fairLock");
        // 最多等待 11秒 加锁三秒
        boolean b = lock.tryLock(11, 3, TimeUnit.SECONDS);
        if (b) {
            System.out.println("B方法 已获得到锁" + DateUtils.getCurrentTime());
        } else {
            System.out.println("B方法 没有获得到锁" + DateUtils.getCurrentTime());
        }
        return "ok";
    }


    /**
     * 信号量隔离
     *
     * @return
     */
    @SneakyThrows
    @RequestMapping("A4")
    public String A4() {
        RSemaphore rSemaphore = redissonClient.getSemaphore("fairLock");
        // 获取一个信号 获取不到只能等待
        rSemaphore.acquire();
        System.out.println("A方法 已获取一个信号" + DateUtils.getCurrentTime());
        return "ok";
    }


    @SneakyThrows
    @RequestMapping("B4")
    public String B4() {
        RSemaphore rSemaphore = redissonClient.getSemaphore("fairLock");
        rSemaphore.release(); //释放一个信号
        System.out.println("B方法 已释放一个信号" + DateUtils.getCurrentTime());
        return "ok";
    }


    @SneakyThrows
    @RequestMapping("A5")
    public String A5() {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.trySetCount(5);// 等待五个 都走完 才能结束
        // 等待闭锁都完成
        door.await(); // 走一个
        return "五个都走完了";
    }


    @SneakyThrows
    @RequestMapping("B5")
    public String B5() {
        RCountDownLatch door = redissonClient.getCountDownLatch("door");
        door.countDown();// 计数减一
        return "ok";
    }

    @SneakyThrows
    @RequestMapping("A6")
    public String A6() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.readLock();
        rLock.lock();
        rLock.unlock();
        return "五个都走完了";
    }


    @SneakyThrows
    @RequestMapping("B6")
    public String B6() {
        RReadWriteLock readWriteLock = redissonClient.getReadWriteLock("rw-lock");
        RLock rLock = readWriteLock.writeLock();
        rLock.lock();
        Thread.sleep(10000);
        rLock.unlock();
        System.out.println("写锁已经解锁");
        return "ok";
    }
}
